#pragma once

//##ModelId=44CF17570302
template<typename NodeType>
class CJoySingleListTraits
{
public:
	//##ModelId=44CF17570313
    typedef NodeType CNode;
	//##ModelId=44CF1757030E
    static CNode* AllocNode()
    {
        return new CNode();
    }
	//##ModelId=44CF17570310
    static void FreeNode(CNode* pNode)
    {
        delete pNode;
    }
};

//##ModelId=44CF1757031C
template<typename NodeType>
class CJoySingleList
{
public:
	//##ModelId=44CF1757033F
    typedef NodeType CNode;
	//##ModelId=44CF17570341
    typedef CJoySingleListTraits<CNode> CTraits;

	//##ModelId=44CF1757031F
    CNode*  m_head;
	//##ModelId=44CF17570324
    CNode*  m_tail;

	//##ModelId=44CF1757032E
    CJoySingleList(void)
    {
        m_head = NULL;
        m_tail = NULL;
    }
	//##ModelId=44CF17570330
    ~CJoySingleList(void)
    {
        Clear();
    }
	//##ModelId=44CF17570332
    void Clear()
    {
        while(m_head != NULL)
        {
            CNode* pNode = m_head;
            m_head = m_head->m_next;
            CTraits::FreeNode(pNode);
        }
        m_tail = NULL;
    }

	//##ModelId=44CF17570333
    void AddTail(CNode* pNode)
    {
        pNode->m_next = NULL;
        if(m_tail != NULL)
        {
            m_tail->m_next = pNode;
        }
        else
        {
            m_head = pNode;
        }
        m_tail = pNode;
    }
	//##ModelId=44CF17570335
    CNode* PeekHead()
    {
        CNode* pNode = m_head;
        if(m_head != NULL)
        {
            ASSERT(m_tail != NULL);
            m_head = m_head->m_next;
            if(m_head == NULL)
            {
                m_tail = NULL;
            }
        }
        return pNode;
    }
	//##ModelId=44CF1757033C
    CNode* PeekAll()
    {
        CNode* pNode = m_head;
        m_head = NULL;
        m_tail = NULL;
        return pNode;
    }

	//##ModelId=44CF1757033D
    bool IsEmpty() const
    {
        return m_head == NULL;
    }
};
